﻿using System;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
//using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using ZYCommon;
using System.Data.OracleClient;
using System.Data.SqlClient;
using Bifrost;

namespace ZYCommon
{
    public class ZYDBConnection : IDisposable
    {
        private bool bolAlertDelete = false;
        private bool bolAutoClose = false;
        private bool bolAutoOpen = true;//自动打开连接
        private bool bolCancelFlag = false;//取消标记
        private bool bolCanUpdate = true;//可以更新
        private int intIdleTimeOut = 0;//用户登录到退出的实效的时间 毫秒数
        private int intLastTick = 0;
        protected IDbConnection myConn = null;//数据源连接
        private static ZYDBConnection myStaticConn = null;
        public EventHandler OnClose = null;
        public EventHandler OnOpen = null;

        public event EventHandler OnCancelFlagChanged;

        //添加参数
        public static IDbDataParameter AddParameter(IDbCommand myCmd, object objValue)
        {
            if (myCmd != null)
            {
                IDbDataParameter myParam = myCmd.CreateParameter();
                if (myParam != null)
                {
                    // myParam.ParameterName = "OBJECTID";
                    //string str = myParam.ParameterName;
                    myParam.Value = objValue;
                    myCmd.Parameters.Add(myParam);
                    return myParam;
                }
            }
            return null;
        }

        public void Close()
        {
            if (this.OnClose != null)
            {
                this.OnClose(this, null);
            }
            if ((this.myConn != null) && (this.myConn.State == ConnectionState.Open))
            {
                this.myConn.Close();
            }
        }

        //创建不同连接类型的关系数据库的 DataAdapter
        public DbDataAdapter CreateAdapter()
        {
            if (this.isOpened())
            {
                if (this.myConn is SqlConnection)//sql连接
                {
                    return new SqlDataAdapter();
                }
                if (this.myConn is OleDbConnection)//ole连接
                {
                    return new OleDbDataAdapter();
                }
            }
            return null;
        }

        //创建并返回一个与该连接相关联的Command对象
        public IDbCommand CreateCommand()
        {
            if (this.isOpened())
            {
                return this.myConn.CreateCommand();
            }
            return null;
        }

        //判断是否是删除记录
        public bool DeleteRecord(ZYDBRecordBase myRecord)
        {
            return this.ExecuteOneRecord(myRecord, 1);
        }

        public void Dispose()
        {
            if (this.myConn != null)
            {
                this.AutoOpen = false;
                this.Close();
                this.myConn.Dispose();
            }
        }

        public void ExecuteCompleted()
        {
            if (this.bolAutoClose)
            {
                this.Close();
            }
        }

        //根据传入的参数 处理不同的记录 返回标记 (是否是新创建记录 是否更新)
        protected bool ExecuteOneRecord(ZYDBRecordBase myRecord, int intType)
        {
            bool bolResult = false;
            if ((myRecord == null))//|| !this.isOpened()
            {
                return bolResult;
            }
            using (IDbCommand myCmd = this.CreateCommand())
            {
                this.intLastTick = Environment.TickCount;
                switch (intType)
                {
                    case 0:
                        //if (myRecord.SetSelectCommandForOneRecord(myCmd, this))
                        //{           
                        //myCmd.CommandText = "Select ObjectID , ObjectName , ObjectType  , ObjectData From ET_Document Where ObjectID = 13";


                        //DataSet ds = myRecord.GetRecordDs(null, this);
                        //if (ds != null)
                        //{
                        //    IDataReader myReader = ds.CreateDataReader(ds.Tables[0]);
                        //    IDataReader myReader = myCmd.ExecuteReader(CommandBehavior .SingleRow );

                        //     myCmd.CommandText = "select * from table_f";
                        //    IDataReader myReader = myCmd.ExecuteReader();
                        //    if (myReader.Read() && myRecord.FromReader(myReader, this))
                        //    {
                        //        bolResult = true;
                        //        myRecord.DataState = DataRowState.Unchanged;
                        //    }
                        //    myReader.Close();
                        //     }
                        //}
                        //goto Label_00FF;
                        return false;
                    case 1:
                        if (myRecord.isKeyEnable() && myRecord.SetDeleteCommand(myCmd, this))
                        {
                            myCmd.ExecuteNonQuery();
                            bolResult = true;
                        }
                        goto Label_00FF;

                    case 2:
                        if (myRecord.SetUpdateCommnad(myCmd, this))
                        {
                            myCmd.ExecuteNonQuery();
                            myRecord.DataState = DataRowState.Unchanged;
                            bolResult = true;
                        }
                        goto Label_00FF;

                    case 3:
                        if (myRecord.SetInsertCommnad(myCmd, this))
                        {
                            myCmd.ExecuteNonQuery();
                            myRecord.DataState = DataRowState.Unchanged;
                            bolResult = true;
                        }
                        goto Label_00FF;

                    case 4:
                        break;

                    default:
                        goto Label_00FF;
                }
                if (myRecord.SetTestExistCommand(myCmd, this))
                {
                    IDataReader myReader = myCmd.ExecuteReader(CommandBehavior.SingleRow);
                    bolResult = myReader.Read();
                    myReader.Close();
                }
            }
        Label_00FF:
            //this.ExecuteCompleted();
            return bolResult;
        }

        //设置参数值
        private void FixParameterValue(IDataParameterCollection myPs)
        {
            if (myPs != null)
            {
                foreach (IDataParameter myP in myPs)
                {
                    if ((myP.Value is string) && StringCommon.isBlankString((string)myP.Value))
                    {
                        myP.Value = " ";
                    }
                }
            }
        }

        public static int[] GetInt32ValueList(IDbCommand myCmd)
        {
            if (myCmd != null)
            {
                Int32Buffer myBuffer = new Int32Buffer();
                IDataReader myReader = myCmd.ExecuteReader(CommandBehavior.SingleResult);
                while (myReader.Read())
                {
                    myBuffer.Append(Convert.ToInt32(myReader[0]));
                }
                myReader.Close();
                return myBuffer.ToArray();
            }
            return null;
        }

        public static string GetSingleValue(IDbCommand myCmd)
        {
            if (myCmd != null)
            {
                IDataReader myReader = myCmd.ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult);
                string strValue = null;
                if (myReader.Read() && !myReader.IsDBNull(0))
                {
                    strValue = myReader[0].ToString();
                }
                myReader.Close();
                return strValue;
            }
            return null;
        }

        public string GetSingleValue(string strSQL)
        {
            if (StringCommon.HasContent(strSQL) && this.isOpened())//判断strSQL不为空，且空白字符之后是否还有字符
            {
                using (IDbCommand myCmd = this.CreateCommand())
                {
                    myCmd.CommandText = strSQL;
                    return GetSingleValue(myCmd);
                }
            }
            return null;
        }

        public string[] GetValueList(string strSQL)
        {
            return this.GetValueList(strSQL, false, false);
        }

        public static string[] GetValueList(IDbCommand cmd, bool OnlyFirstField, bool OnlyFirstRecord)
        {
            IDataReader myReader;
            ArrayList myList = new ArrayList();
            if (OnlyFirstRecord)
            {
                myReader = cmd.ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult);
            }
            else
            {
                myReader = cmd.ExecuteReader(CommandBehavior.SingleResult);
            }
            while (myReader.Read())
            {
                if (OnlyFirstField || (myReader.FieldCount == 1))
                {
                    myList.Add(myReader.IsDBNull(0) ? null : myReader[0].ToString());
                }
                else
                {
                    for (int iCount = 0; iCount < myReader.FieldCount; iCount++)
                    {
                        myList.Add(myReader.IsDBNull(iCount) ? null : myReader[iCount].ToString());
                    }
                }
                if (OnlyFirstRecord)
                {
                    break;
                }
            }
            myReader.Close();
            return (string[])myList.ToArray(typeof(string));
        }


        public string[] GetValueList(string strSQL, bool OnlyFirstField, bool OnlyFirstRecord)
        {
            if (StringCommon.isBlankString(strSQL) || !this.isOpened())
            {
                return null;
            }
            string[] strResult = null;
            using (IDbCommand cmd = this.CreateCommand())
            {
                cmd.CommandText = strSQL;
                strResult = GetValueList(cmd, OnlyFirstField, OnlyFirstRecord);
            }
            this.ExecuteCompleted();
            return strResult;
        }

        //判断数据源是否打开
        public bool isOpened()
        {
            if (this.CancelFlag)
            {
                return false;
            }
            if (this.OnOpen != null)
            {
                this.OnOpen(this, null);
            }
            if (this.myConn == null)
            {
                return false;
            }
            if (this.myConn.State != ConnectionState.Open)
            {
                if (!this.bolAutoOpen)
                {
                    return false;
                }
                if (this.myConn.State == ConnectionState.Connecting)//如果连接对象正在与数据源连接
                {
                    //using (dlgWaiting dlg = new dlgWaiting())//新创建一个等待窗体
                    //{
                    //    dlg.TopMost = true;//顶层窗体
                    //    dlg.Show();//显示
                    //    dlg.ShowCancelButton = true;
                    //    while (this.myConn.State == ConnectionState.Connecting)
                    //    {
                    //        Application.DoEvents();//处理当前在消息队列里面的所有信息
                    //        if (dlg.DialogResult == DialogResult.Cancel)
                    //        {
                    //            return false;
                    //        }
                    //    }
                    //    dlg.Close();
                    //}
                }
                else
                {
                    this.myConn.Open();
                }
            }
            return true;
        }

        //判断是否新记录
        public bool NewRecord(ZYDBRecordBase myRecord)
        {
            return this.ExecuteOneRecord(myRecord, 3);
        }

        public void Open()
        {
            if (this.OnOpen != null)
            {
                this.OnOpen(this, null);
            }
            if (this.myConn.State != ConnectionState.Open)
            {
                this.myConn.Open();
            }
        }

        public ArrayList ReadAllRecords(ZYDBRecordBase myRecord)
        {
            ArrayList myList = new ArrayList();
            if (this.ReadAllRecords(myList, myRecord) >= 0)
            {
                return myList;
            }
            return null;
        }

        //读取所有记录 返回记录总数
        public int ReadAllRecords(ArrayList myList, ZYDBRecordBase myRecord)
        {
            if (((myList != null) && (myRecord != null)) && this.isOpened())
            {
                using (IDbCommand myCmd = this.CreateCommand())
                {
                    this.intLastTick = Environment.TickCount;
                    if (myRecord.SetSelectAllCommand(myCmd, this))
                    {
                        IDataReader myReader = myCmd.ExecuteReader();
                        if (myReader != null)
                        {
                            int iCount = this.ReadRecordsFromReader(myList, myRecord, myReader);
                            myReader.Close();
                            this.ExecuteCompleted();
                            return iCount;
                        }
                    }
                }
            }
            return -1;
        }

        public bool ReadOneRecord(ZYDBRecordBase myRecord)
        {
            return this.ExecuteOneRecord(myRecord, 0);
        }

        public ArrayList ReadRecords(ZYDBRecordBase myRecord)
        {
            ArrayList myList = new ArrayList();
            if (this.ReadRecords(myList, myRecord) >= 0)
            {
                return myList;
            }
            return null;
        }

        //读取记录 返回读取的记录数
        public int ReadRecords(ArrayList myList, ZYDBRecordBase myRecord)
        {
            if (((myList != null) && (myRecord != null)) && this.isOpened())
            {
                using (IDbCommand myCmd = this.CreateCommand())
                {
                    this.intLastTick = Environment.TickCount;
                    if (myRecord.SetSelectCommand(myCmd, this))
                    {
                        ZYErrorReport.Instance.DebugPrint("查询数据：SQL语句:" + myCmd.CommandText);
                        IDataReader myReader = myCmd.ExecuteReader();
                        int iCount = this.ReadRecordsFromReader(myList, myRecord, myReader);
                        ZYErrorReport.Instance.DebugPrint("供查询 " + iCount + " 条记录");
                        myReader.Close();
                        this.ExecuteCompleted();
                        return iCount;
                    }
                }
            }
            return -1;
        }

        public ArrayList ReadRecords(ZYDBRecordBase myRecord, IDbCommand myCmd)
        {
            ArrayList myList = new ArrayList();
            if (this.ReadRecords(myList, myRecord, myCmd) >= 0)
            {
                return myList;
            }
            return null;
        }

        public ArrayList ReadRecords(ZYDBRecordBase myRecord, string strSQL)
        {
            ArrayList myList = new ArrayList();
            if (this.ReadRecords(myList, myRecord, strSQL) >= 0)
            {
                return myList;
            }
            return null;
        }

        public int ReadRecords(ArrayList myList, ZYDBRecordBase myRecord, IDbCommand myCmd)
        {
            if (((myList != null) && (myRecord != null)) && (myCmd != null))
            {
                ZYErrorReport.Instance.DebugPrint("读取数据" + myCmd.CommandText);
                this.intLastTick = Environment.TickCount;
                IDataReader myReader = myCmd.ExecuteReader();
                ZYErrorReport.Instance.DebugPrint("myList=" + myList);
                ZYErrorReport.Instance.DebugPrint("myRecord=" + myRecord);
                ZYErrorReport.Instance.DebugPrint("myReader=" + myReader);
                if (myReader == null)
                {
                    return -1;
                }
                int iCount = this.ReadRecordsFromReader(myList, myRecord, myReader);
                ZYErrorReport.Instance.DebugPrint("共读取" + iCount + "条记录");
                myReader.Close();
                return iCount;
            }
            return -1;
        }

        public int ReadRecords(ArrayList myList, ZYDBRecordBase myRecord, string strSQL)
        {
            int flag = -1;
            if (((myList != null) && (myRecord != null)))//&& this.isOpened()
            {
                //using (IDbCommand myCmd = this.CreateCommand())
                //{
                this.intLastTick = Environment.TickCount;
                //myCmd.CommandText = strSQL;
                //IDataReader myReader = myCmd.ExecuteReader();myReader

                DataSet ds = App.GetDataSet(strSQL);
                int iCount = this.ReadRecordsFromReader(myList, myRecord, ds.CreateDataReader(ds.Tables[0]));
                //myReader.Close();
                //this.ExecuteCompleted();
                flag = iCount;
                // }
            }
            return flag;
        }

        //从结果集中读取记录 返回读取的记录数
        public int ReadRecordsFromReader(ArrayList myList, ZYDBRecordBase myRecord, IDataReader myReader)
        {
            if (((myList != null) && (myRecord != null)) && (myReader != null))
            {
                int iCount = 0;
                while (myReader.Read())
                {
                    ZYDBRecordBase NewRecord = myRecord.CreateNewRecord();
                    if (!NewRecord.FromReader(myReader, this))
                    {
                        return iCount;
                    }
                    NewRecord.DataState = DataRowState.Unchanged;
                    myList.Add(NewRecord);
                    iCount++;
                }
                return iCount;
            }
            return -1;
        }

        ////从结果集中读取记录 返回读取的记录数
        //public int ReadRecordsFromReader(ArrayList myList, ZYDBRecordBase myRecord, DataSet  myDs)
        //{
        //    if (((myList != null) && (myRecord != null)) && (myDs  != null))
        //    {myDs .CreateDataReade
        //        int iCount = 0;
        //        for (int i = 0; i < myDs.Tables[0].Rows.Count; i++)
        //        {
        //            ZYDBRecordBase NewRecord = myRecord.CreateNewRecord();

        //        }
        //        //while (myReader.Read())
        //        //{
        //        //    ZYDBRecordBase NewRecord = myRecord.CreateNewRecord();
        //        //    if (!NewRecord.FromReader(myReader, this))
        //        //    {
        //        //        return iCount;
        //        //    }
        //        //    NewRecord.DataState = DataRowState.Unchanged;
        //        //    myList.Add(NewRecord);
        //        //    iCount++;
        //        //}
        //        return iCount;
        //    }
        //    return -1;
        //}

        //判断用户登录是否超时
        public bool TestIdleTimeOut()
        {
            if (((this.intIdleTimeOut > 0) && (this.intLastTick > 0)) && (((Environment.TickCount - this.intLastTick) > this.intIdleTimeOut) && this.isOpened()))
            {
                this.intLastTick = Environment.TickCount;
                this.myConn.Close();
                return true;
            }
            return false;
        }

        //判断记录是否已经存在
        public bool TestRecordExist(ZYDBRecordBase myRecord)
        {
            return this.ExecuteOneRecord(myRecord, 4);
        }

        //更新记录 并返回更新是否成功标记
        public bool UpdateRecord(ZYDBRecordBase myRecord)
        {
            return this.ExecuteOneRecord(myRecord, 2);
        }

        //自动更新记录
        public bool UpdateRecordAuto(ZYDBRecordBase myRecord)
        {
            ArrayList myList = new ArrayList();
            myList.Add(myRecord);
            return (this.UpdateRecords(myList, null) == 1);
        }

        //更新记录  并返回更新的记录条数
        public int UpdateRecords(ArrayList myList, ProgressHandler vProgress)
        {
            int iCount = -1;
            if ((myList != null) && this.isOpened())
            {
                if (this.bolAlertDelete)
                {
                    foreach (ZYDBRecordBase r in myList)
                    {
                        r.UpdateSuccess = false;
                    }
                }
                using (IDbCommand myCmd = this.CreateCommand())
                {
                    iCount = 0;
                    for (int index = 0; index < myList.Count; index++)
                    {
                        if (vProgress != null)
                        {
                            vProgress(index, myList.Count);
                        }
                        ZYDBRecordBase myRecord = (ZYDBRecordBase)myList[index];
                        myCmd.Parameters.Clear();
                        DataRowState CS0000000200000003 = myRecord.DataState;
                        if (CS0000000200000003 != DataRowState.Added)
                        {
                            if (CS0000000200000003 == DataRowState.Deleted)//如果是删除数据 跳转到标签Label_014A处
                            {
                                goto Label_014A;
                            }
                            if (CS0000000200000003 == DataRowState.Modified)//如果是修改数据 跳转到标签Label_019F处
                            {
                                goto Label_019F;
                            }
                        }
                        else//增加数据行
                        {
                            //如果当前记录没有序列值(seq)，就查询数据库中的seq 然后设置seq的值
                            if ((!myRecord.isKeyEnable() && myRecord.SetAllocKeyCommand(myCmd, this)) && !myRecord.isKeyEnable())
                            {
                                IDataReader myReader = myCmd.ExecuteReader(CommandBehavior.SingleRow);
                                if (myReader.Read())
                                {
                                    string strKey = myReader.IsDBNull(0) ? null : myReader[0].ToString();
                                    myRecord.SetKeyWord(strKey);
                                }
                                myReader.Close();
                            }
                            if (myRecord.isKeyEnable() && myRecord.SetInsertCommnad(myCmd, this))
                            {
                                this.FixParameterValue(myCmd.Parameters);
                                myCmd.ExecuteNonQuery();//执行sql并返回受影响的行数
                                myRecord.DataState = DataRowState.Unchanged;
                                iCount++;
                            }
                        }
                        goto Label_01CB;
                    Label_014A:
                        if (myRecord.CustomDelete(myCmd, this))
                        {
                            myList.Remove(myRecord);
                            index--;
                            iCount++;
                        }
                        else
                        {
                            myCmd.Parameters.Clear();
                            if (myRecord.isKeyEnable() && myRecord.SetDeleteCommand(myCmd, this))
                            {
                                myCmd.ExecuteNonQuery();
                                myList.Remove(myRecord);
                                index--;
                                iCount++;
                            }
                        }
                        goto Label_01CB;
                    Label_019F:
                        if (myRecord.SetUpdateCommnad(myCmd, this))
                        {
                            this.FixParameterValue(myCmd.Parameters);
                            myCmd.ExecuteNonQuery();
                            myRecord.DataState = DataRowState.Unchanged;
                            iCount++;
                        }
                    Label_01CB:
                        myRecord.UpdateSuccess = true;
                    }
                }
                this.ExecuteCompleted();
            }
            return iCount;
        }

        public bool AlertDelete
        {
            get
            {
                return this.bolAlertDelete;
            }
            set
            {
                this.bolAlertDelete = value;
            }
        }

        public bool AutoClose
        {
            get
            {
                return this.bolAutoClose;
            }
            set
            {
                this.bolAutoClose = value;
            }
        }

        public bool AutoOpen
        {
            get
            {
                return this.bolAutoOpen;
            }
            set
            {
                this.bolAutoOpen = value;
            }
        }

        public bool CancelFlag
        {
            get
            {
                return this.bolCancelFlag;
            }
            set
            {
                this.bolCancelFlag = value;
                if (this.OnCancelFlagChanged != null)
                {
                    this.OnCancelFlagChanged(this, null);
                }
            }
        }

        public bool CanRead
        {
            get
            {
                return (this.myConn != null);
            }
        }

        public bool CanUpdate
        {
            get
            {
                return this.bolCanUpdate;
            }
            set
            {
                this.bolCanUpdate = value;
            }
        }

        public IDbConnection Connection
        {
            get
            {
                return this.myConn;
            }
            set
            {
                this.myConn = value;
            }
        }

        public string ConnectionString
        {
            get
            {
                return this.myConn.ConnectionString;
            }
            set
            {
                this.myConn.ConnectionString = value;
            }
        }

        public int IdleTimeOut
        {
            get
            {
                return this.intIdleTimeOut;
            }
            set
            {
                this.intIdleTimeOut = value;
            }
        }

        //获得连接实例
        public static ZYDBConnection Instance
        {
            get
            {
                if (myStaticConn == null)
                {
                    myStaticConn = new ZYDBConnection();
                }
                return myStaticConn;
            }
            set
            {
                myStaticConn = value;
            }
        }

        //判断数据库连接 设置连接语句
        public bool IsJet40
        {
            get
            {
                return (((this.myConn != null) && (this.myConn is OleDbConnection)) && ((this.myConn as OleDbConnection).Provider.ToUpper() == "MICROSOFT.JET.OLEDB.4.0"));
            }
        }

        //判断是否是Oracle数据库 设置连接语句
        public bool IsOracle
        {
            get
            {
                if ((this.myConn != null) && (this.myConn is OleDbConnection))
                {
                    string strProvider = (this.myConn as OleDbConnection).Provider;
                    return (strProvider.StartsWith("OraOLEDB.Oracle") || strProvider.StartsWith("MSDAORA"));
                }
                return false;
            }
        }

        //判断是否是SQLServer 设置连接的语句
        public bool IsSQLServer
        {
            get
            {
                if (this.myConn != null)
                {
                    if (this.myConn is SqlConnection)
                    {
                        return true;
                    }
                    if (this.myConn is OleDbConnection)
                    {
                        return (this.myConn as OleDbConnection).Provider.StartsWith("SQLOLEDB");
                    }
                }
                return false;
            }
        }
    }
}

